import superTableRender from '@/components/amis/SuperTable/superTableRender'
import { SuperTableProps } from '@/components/amis/SuperTable/types'
import { ActionSchema, ButtonSchema, FormSchema } from 'amis'
import { CRUDBultinToolbarType, CRUDTableSchema, CRUDToolbarChild, CRUDToolbarObject } from 'amis/lib/renderers/CRUD'
import serverApiUtils from '@/core/utils/serverApiUtils'
import { OperationSchema } from 'amis/lib/renderers/Operation'
import DefaultCrudTableProps, { DefaultCrudTableServerApi } from './types/DefaultCrudTableProps'
import { Schema } from 'amis/lib/types'
import { ApiObject } from 'amis-core/lib/types'
import { isNil, isUndefined } from 'lodash-es'
import { AjaxActionSchema } from 'amis/lib/renderers/Action'
import './defaultCrudTableUtils.less'
import { DrawerSchema } from 'amis/lib/renderers/Drawer'
import lodash from 'lodash'

class DefaultCrudTableUtils {
	getSchema = (params: DefaultCrudTableProps): Schema => {
		const { primaryField, title, debug } = Object.assign(
			{
				debug: false,
				primaryField: 'id',
				title: `${params.entityTitle}列表`,
			},
			params,
		)
		const addServerApi = this.getServerApiProps(params.addServerApi)
		const detailServerApi = this.getServerApiProps(params.detailServerApi)
		if (detailServerApi) {
			detailServerApi.data = Object.assign({ id: '${id}' }, detailServerApi.data)
		}
		const modifyServerApi = this.getServerApiProps(params.editServerApi)
		const searchServerApi = this.getServerApiProps(params.searchServerApi)
		const deleteServerApi = this.getServerApiProps(params.deleteServerApi)
		if (deleteServerApi) {
			deleteServerApi.data = Object.assign(
				{
					id: '${ids|split}',
				},
				deleteServerApi.data,
			)
		}
		const newFormSchema = {
			type: 'form',
			api: addServerApi,
			debug: debug,
			data: params.newFormData,
			body: params.formItems,
		} as FormSchema

		const editorFormSchema = {
			type: 'form',
			initApi: detailServerApi,
			api: modifyServerApi,
			debug: debug,
			data: Object.assign(
				{
					isEditMode: true,
				},
				params.editorFormData,
			),
			canAccessSuperData: false,
			body: params.formItems,
		} as FormSchema
		let bulkActions = undefined
		if (params.deleteServerApi) {
			bulkActions = [
				{
					type: 'button',
					label: '删除',
					actionType: 'ajax',
					api: deleteServerApi,
					confirmText: '确定要批量删除吗?',
				} as AjaxActionSchema,
			]
		}
		const headerToolbar: Array<(CRUDToolbarChild & CRUDToolbarObject) | CRUDBultinToolbarType> | undefined = []
		if (addServerApi) {
			const newButtonSchema = this.getNewButtonSchema(params, newFormSchema)
			headerToolbar.push(newButtonSchema)
		}
		if (params.toolButtons && params.toolButtons.length > 0) {
			headerToolbar.push(...params.toolButtons)
		}

		const operationButtons = []

		if (modifyServerApi) {
			const editButtonSchema = this.getEditButtonSchema(params, editorFormSchema)
			operationButtons.push(editButtonSchema)
		}

		let operationCol = undefined
		if (operationButtons.length > 0) {
			operationCol = {
				type: 'operation',
				label: '操作',
				fixed: 'right',
				buttons: operationButtons,
			} as OperationSchema
		}

		if (params.operationButtons && params.operationButtons.length > 0) {
			operationButtons.push(...params.operationButtons)
		}

		const superTableSchema = superTableRender.getSchema({
			title: title,
			tableSchema: {
				api: searchServerApi,
				className: 'antd-crud-super-table',
				bulkActions: bulkActions,
				headerToolbar: headerToolbar,
				columns: [
					{
						type: 'ace-col-index',
						label: '#',
						width: 20,
					},
					...params.columns,
					...(operationCol ? [operationCol] : []),
				],
			} as CRUDTableSchema,
		} as SuperTableProps)
		let schema = superTableSchema
		return schema
	}

	private getServerApiProps(serverApi: DefaultCrudTableServerApi): ApiObject | undefined {
		if (isNil(serverApi)) {
			return undefined
		}
		let result: ApiObject = Object.assign({} as ApiObject, serverApi)
		if (!isUndefined(serverApi.apiConfig)) {
			result.url = serverApiUtils.getUriOrMockUri(serverApi.apiConfig)
			result.method = serverApi.apiConfig.method as 'get' | 'post' | 'put' | 'delete' | 'patch' | 'jsonp' | 'js'
		}
		console.log('getServerApiProps_result', result)
		return result
	}

	private getNewButtonSchema = (params: DefaultCrudTableProps, newFormSchema: FormSchema): ButtonSchema => {
		const buttonSchema = {
			label: '新增',
			type: 'button',
			level: 'primary',
		} as ActionSchema
		if (params.editorType === 'dialog') {
			return Object.assign(buttonSchema, {
				actionType: 'dialog',
				dialog: {
					title: `新增 [${params.entityTitle}] (Esc退出)`,
					showErrorMsg: false,
					closeOnEsc: true,
					body: newFormSchema,
				},
			})
		}
		const drawerButtonSchema = Object.assign(buttonSchema, {
			actionType: 'drawer',
			drawer: {
				title: `新增 [${params.entityTitle}] (Esc退出)`,
				showErrorMsg: false,
				position: 'right',
				closeOnEsc: true,
				resizable: true,
				body: newFormSchema,
			} as Partial<DrawerSchema>,
		} as Partial<ActionSchema>)
		return drawerButtonSchema
	}

	private getEditButtonSchema = (params: DefaultCrudTableProps, editorFormSchema: FormSchema): ButtonSchema => {
		const buttonSchema = {
			label: '编辑',
			type: 'button',
			level: 'link',
		} as ActionSchema
		if (params.editorType === 'dialog') {
			return lodash.merge(
				buttonSchema,
				{
					actionType: 'dialog',
					dialog: {
						title: `编辑 [${params.entityTitle}] (Esc退出)`,
						showErrorMsg: false,
						closeOnEsc: true,
						body: editorFormSchema,
					},
				},
				params.editButton,
			)
		}
		const drawerButtonSchema = lodash.merge(
			buttonSchema,
			{
				actionType: 'drawer',
				drawer: {
					title: `编辑 [${params.entityTitle}] (Esc退出)`,
					showErrorMsg: false,
					position: 'right',
					closeOnEsc: true,
					resizable: true,
					body: editorFormSchema,
				} as Partial<DrawerSchema>,
			} as Partial<ActionSchema>,
			params.editButton,
		)
		return drawerButtonSchema
	}
}

export default new DefaultCrudTableUtils()
